<template>
  <div @click="show" class="slot-item">
    <slot></slot>
  </div>
  <ModalPanel :visible="visible" :title="t('表单设置')" @submit="submit" @close="close">
    <template #left>
      <Category v-model="setting.checkFormType" @change="changeType" />
    </template>
    <SelectedList type="form" :list="setting.selectedList" @abolish="abolishChecked" />
    <SearchBox @search="searchList" />
    <div class="flow-used" v-if="setting.checkFormType == FormType.WORKFLOW">
      <EmptyBox v-if="showUsedEmpty" />
      <!-- 仅仅显示未重复表单 -->
      <div class="list-page-box" v-if="showRepeatedList">
        <FormCard
          v-for="(noUsedItem, index) in setting.usedNotRepeatedList"
          :key="index"
          :item="setting.formKeyList[noUsedItem]"
          @click="usedChecked(noUsedItem)"
          :class="selectKeys.includes(noUsedItem) ? 'picked' : 'notPicked'"
          class="notPicked"
        >
          <template #check>
            <a-checkbox size="small" :checked="selectKeys.includes(noUsedItem)" />
          </template>
        </FormCard>
      </div>
      <!-- 既有重复表单又有未重复表单 显示面板折叠分类 -->
      <a-collapse v-else v-model:activeKey="activeKey" ghost expandIconPosition="right">
        <a-collapse-panel
          v-for="(formIds, formIndex) in setting.usedRepeatedList"
          :key="formIndex"
          :header="t('相同表单重复选用-') + setting.formKeyList[formIds[0]].name"
        >
          <div class="list-page-box" v-if="formIds.length > 0">
            <FormCard
              v-for="(key, index) in formIds"
              :key="index"
              :item="setting.formKeyList[key]"
              :class="selectKeys.includes(key) ? 'picked' : 'notPicked'"
              @click="usedChecked(key)"
            >
              <template #check>
                <a-checkbox size="small" :checked="selectKeys.includes(key)" />
              </template>
            </FormCard>
          </div>
        </a-collapse-panel>
        <a-collapse-panel
          key="2000"
          :header="t('未重复选用的表单')"
          v-if="setting.usedNotRepeatedList.length > 0"
        >
          <div class="list-page-box">
            <FormCard
              v-for="(noUsedItem, index) in setting.usedNotRepeatedList"
              :key="index"
              :item="setting.formKeyList[noUsedItem]"
              @click="usedChecked(noUsedItem)"
              :class="selectKeys.includes(noUsedItem) ? 'picked' : 'notPicked'"
              class="notPicked"
            >
              <template #check>
                <a-checkbox size="small" :checked="selectKeys.includes(noUsedItem)" />
              </template>
            </FormCard>
          </div>
        </a-collapse-panel>
      </a-collapse>
    </div>
    <template v-else>
      <div class="list-page-box" v-if="setting.list.length > 0">
        <FormCard
          v-for="(item, index) in setting.list"
          :key="index"
          :item="item"
          :class="setting.checkedFormId[item.formId] ? 'picked' : 'notPicked'"
          @click="checked(item)"
        >
          <template #check>
            <a-checkbox
              size="small"
              :checked="setting.checkedFormId[item.formId] ? true : false"
              :disabled="item.enabledMark == 1 ? false : true"
            />
          </template>
        </FormCard>
        <div class="page-box">
          <a-pagination
            v-model:current="setting.page.current"
            :pageSize="setting.page.pageSize"
            :total="setting.page.total"
            show-less-items
            @change="getList"
          />
        </div>
      </div>
      <EmptyBox v-else />
    </template>
  </ModalPanel>
  <a-modal
    v-model:visible="setting.operationVisible"
    :width="400"
    :title="t('操作确认')"
    @ok="submitOperation"
  >
    <div class="opr-box">
      <div class="opr-icon">
        <Icon icon="ant-design:question-circle-outlined" :size="30" color="#ff9900" />
      </div>
      <div class="opr-content">
        <div class="title">{{ t('该表单已经在流程中引用过，是否重复引用？') }}</div>
        <div class="desc">{{ t('重复引用是在发起或审批中，会出现两张相同结构的表单。') }}</div>
      </div>
    </div>
  </a-modal>
</template>

<script setup lang="ts">
  import { computed, reactive, ref } from 'vue';
  import { message } from 'ant-design-vue';
  import { ModalPanel, SearchBox, EmptyBox } from '/@/components/ModalPanel/index';
  import Category from '/@bpmn/components/formSettings/Category.vue';
  import SelectedList from '/@bpmn/components/formSettings/SelectedList.vue';
  import FormCard from '/@bpmn/components/card/FormCard.vue';
  import { FormType } from '/@/enums/workflowEnum';
  import { FormSettingItem } from '/@/model/workflow/formSetting';
  import { getFormTemplateEnabledPage } from '/@/api/form/design';
  import { randomFormNameStr, randomTime } from '/@bpmn/util/random';
  import { getUsedFormIds, getUsedFormList } from '/@bpmn/config/info';
  import { Icon } from '/@/components/Icon';
  import { cloneDeep } from 'lodash-es';
  import { useI18n } from '/@/hooks/web/useI18n';
  const { t } = useI18n();
  let props = withDefaults(defineProps<{ isSingle: Boolean; list: Array<FormSettingItem> }>(), {
    isSingle: () => {
      return false;
    },
    list: () => {
      return [];
    },
  });
  let emits = defineEmits(['submit']);
  const activeKey = ref(['2000']);

  const visible = ref(false);
  let setting: {
    checkFormType: FormType;
    selectedList: Array<FormSettingItem>;
    list: Array<FormSettingItem>;
    searchKeyword: string;
    page: { current: number; total: number; pageSize: number };
    formKeyList: Object;
    checkedFormId: Object;
    usedRepeatedList: Object;
    usedNotRepeatedList: Array<string>;
    operationVisible: boolean;
    operationCloneItem: FormSettingItem;
  } = reactive({
    checkFormType: FormType.CUSTOM,
    selectedList: [],
    list: [],
    searchKeyword: '',
    page: { current: 1, total: 0, pageSize: 9 },
    formKeyList: {},
    checkedFormId: {},
    usedRepeatedList: {},
    usedNotRepeatedList: [],
    operationVisible: false,
    operationCloneItem: {
      key: '', //formId_key
      formType: FormType.CUSTOM, //表单类型
      formId: '', //表单ID   系统表单为文件夹名
      formName: '', //表单名称
    },
  });
  const showRepeatedList = computed(() => {
    return (
      setting.usedNotRepeatedList.length != 0 && JSON.stringify(setting.usedRepeatedList) == '{}'
    );
  });
  const showUsedEmpty = computed(() => {
    return (
      setting.usedNotRepeatedList.length == 0 && JSON.stringify(setting.usedRepeatedList) == '{}'
    );
  });
  let selectKeys = computed(() => {
    if (setting.selectedList && setting.selectedList.length > 0) {
      return setting.selectedList.map((ele: FormSettingItem) => {
        return ele.key;
      });
    }
    return [];
  });
  function show() {
    setting.checkFormType = FormType.CUSTOM;
    setting.list = [];
    setting.page.total = 0;
    setting.selectedList = [];
    getList();
    visible.value = true;
  }
  function changeType() {
    setting.list = [];
    setting.page.total = 0;
    getList();
  }
  async function getList() {
    if (setting.checkFormType == FormType.WORKFLOW) {
      getUsedList();
    } else {
      await getTemplateList();
    }
  }
  function getUsedList() {
    let { formKeyList, repeatedList, notRepeatedList } = getUsedFormList();
    setting.formKeyList = formKeyList;
    setting.usedNotRepeatedList = notRepeatedList;
    setting.usedRepeatedList = repeatedList;
    let arr: Array<string> = [];
    for (let k of Object.keys(setting.usedRepeatedList)) {
      arr.push(k);
    }
    arr.push('2000'); //未重复的表单的卡片key
    activeKey.value = arr;
  }
  async function getTemplateList() {
    let params = {
      limit: setting.page.current,
      size: setting.page.pageSize,
      type: setting.checkFormType,
      keyword: setting.searchKeyword,
    };
    let res = await getFormTemplateEnabledPage(params);
    if (res.total) {
      setting.page.total = res.total;
    }
    setting.list = [];
    if (res.list.length > 0) {
      res.list.forEach((ele) => {
        if (setting.checkFormType == FormType.CUSTOM) {
          setting.list.push({
            key: 'form_' + ele.id + '_' + randomTime(),
            formType: FormType.CUSTOM,
            formName: ele.name ? ele.name : ele.id,
            formId: ele.id,
            enabledMark: ele.enabledMark,
          });
        } else {
          setting.list.push({
            key: 'form_' + ele.id + '_' + randomTime(),
            formType: FormType.SYSTEM,
            formName: ele.name,
            formId: ele.id,
            enabledMark: ele.enabledMark,
          });
        }
      });
    }
  }

  async function submit() {
    if (setting.selectedList.length === 0) {
      message.error(t('请至少选择一个表单'));
      return false;
    }
    emits('submit', setting.selectedList);
    close();
  }
  function close() {
    visible.value = false;
  }
  function searchList(keyword: string) {
    setting.searchKeyword = keyword;
    setting.page.current = 1;
    getList();
  }
  function checked(item: FormSettingItem) {
    if (item.enabledMark != 1) return;
    let cloneItem: FormSettingItem = cloneDeep(item);
    cloneItem.formName = hasFormIdFromSelectedList(cloneItem.formId)
      ? cloneItem.formName + '_' + randomFormNameStr()
      : cloneItem.formName;
    cloneItem.key = 'form_' + cloneItem.formId + '_' + randomTime();
    setting.operationCloneItem = cloneItem;
    if (props.isSingle) {
      // 单选
      setting.selectedList = [];
      setting.checkedFormId = {};
      if (!setting.checkedFormId[item.formId]) {
        if (hasFormIdFromSelectedList(cloneItem.formId)) {
          setting.operationVisible = true;
        } else {
          submitOperation();
        }
      }
    } else {
      // 多选
      if (setting.checkedFormId[item.formId]) {
        // 取消选中
        let formKey = setting.checkedFormId[item.formId];
        if (selectKeys.value.includes(formKey)) {
          let index = setting.selectedList.findIndex((ele) => {
            return ele.key === formKey;
          });
          setting.selectedList.splice(index, 1);
        }
        setting.checkedFormId[item.formId] = '';
      } else {
        if (hasFormIdFromSelectedList(cloneItem.formId)) {
          setting.operationVisible = true;
        } else {
          submitOperation();
        }
      }
    }
  }
  function usedChecked(key: string) {
    if (props.isSingle) {
      let cloneItem: FormSettingItem = cloneDeep(setting.formKeyList[key]);
      setting.selectedList = [cloneItem];
    } else {
      if (selectKeys.value.includes(key)) {
        let index = setting.selectedList.findIndex((ele) => {
          return ele.key === key;
        });
        setting.selectedList.splice(index, 1);
      } else {
        let cloneItem: FormSettingItem = cloneDeep(setting.formKeyList[key]);
        setting.selectedList.push(cloneItem);
      }
    }
  }
  function hasFormIdFromSelectedList(formId) {
    let usedIds = [
      ...getUsedFormIds(),
      ...setting.selectedList.map((ele) => {
        return ele.formId;
      }),
    ];
    return usedIds.includes(formId);
  }
  function submitOperation() {
    let cloneItem: FormSettingItem = setting.operationCloneItem;
    setting.checkedFormId[cloneItem.formId] = cloneItem.key;
    setting.selectedList.push(cloneItem);
    setting.operationVisible = false;
  }

  function abolishChecked(item: FormSettingItem) {
    setting.selectedList = setting.selectedList.filter((ele) => {
      return ele.key != item.key;
    });
    setting.checkedFormId[item.formId] = '';
  }
</script>
<style lang="less" scoped>
  .list-box {
    display: flex;
    flex-wrap: wrap;
    padding: 10px 0;
  }

  .page-box {
    position: absolute;
    bottom: 80px;
    right: 20px;
  }

  .picked {
    border-width: 1px;
    border-style: dotted;
  }

  .notPicked {
    border-width: 1px;
    border-style: dotted;
    border-color: transparent;
  }

  .flow-used {
    height: calc(100% - 100px);
    overflow: auto;
  }

  :deep(.ant-collapse-ghost > .ant-collapse-item) {
    border-bottom: 1px solid #f5f5f5;
  }

  :deep(.ant-collapse-icon-position-right > .ant-collapse-item > .ant-collapse-header) {
    padding: 10px 16px;
  }

  :deep(.ant-collapse-content-box .ant-form-item) {
    margin-bottom: 12px;
  }

  :deep(.ant-collapse-content-box) {
    padding-left: 30px;
  }

  :deep(.ant-input-number) {
    width: 100%;
  }

  .opr-box {
    display: flex;
    padding: 30px 20px;

    .opr-icon {
      margin-right: 10px;
    }

    .opr-content {
      .title {
        font-weight: 700;
      }

      .desc {
        color: #a0a0a0;
      }
    }
  }
</style>
